﻿using Abp.Domain.Repositories;
using Abp.Domain.Services;
using Abp.ObjectMapping;
using Abp.Runtime.Caching;
using Abp.UI;
using AVIS.OutBound.AWD;
using AVIS.OutBound.BookOrders;
using AVIS.OutBound.Orders;
using AVIS.OutBound.RateCodes.Cache;
using AVIS.OutBound.Regions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AVIS.OutBound.RateCodes
{
    public class RateCodeManager : DomainService, IRateCodeManager
    {
        #region 构造函数
        private readonly IRepository<RateCode> _RateCodeRepository;
        private readonly IRegionManager _regionManager;
        private readonly IAWDManager _AWDManager;
        private readonly IObjectMapper _objectMapper;
        private readonly ICacheManager _CacheManager;

        public RateCodeManager(IRepository<RateCode> RateCodeRepository,
            IRegionManager regionManager,
            IAWDManager AWDManager,
            IObjectMapper objectMapper,
            ICacheManager CacheManager)
        {
            _RateCodeRepository = RateCodeRepository;
            _regionManager = regionManager;
            _AWDManager = AWDManager;
            _objectMapper = objectMapper;
            _CacheManager = CacheManager;
        }
        #endregion

        /// <summary>
        /// 获取满足订单的套餐价格代码（最新的4条，如果没有包含默认的，则再加入空的默认套餐）
        /// </summary>
        /// <param name="order">预订单</param>
        /// <returns>套餐价格代码列表（最新的4条，如果没有包含默认的，则再加入空的默认套餐）</returns>
        public List<RateCode> GetRateCodesByOrder(BookOrder order)
        {
            var cache = _CacheManager.GetRateCodeCache();
            var cacheKey = string.Format("{0}-{1}-{2}", order.RentalLength, order.PickUpRegionCode, order.AWD);

            var awdCacheItems = cache.Get(cacheKey,
                f => GetRateCodesInDB(order.RentalLength, order.PickUpRegionCode, order.AWD));

            return _objectMapper.Map<List<RateCode>>(awdCacheItems);
        }

        /// <summary>
        /// 获取指定订单的套餐价格代码（不包含基础套餐）
        /// </summary>
        /// <param name="order">预订单</param>
        /// <returns></returns>
        public RateCode GetRateCode(Order order)
        {
            if (string.IsNullOrWhiteSpace(order.RateCode))
            {
                return null;
            }

            var bookOrder = _objectMapper.Map<BookOrder>(order);
            var list = GetRateCodesByOrder(bookOrder);
            return list.FirstOrDefault(r => r.Code == order.RateCode);
        }


        /// <summary>
        /// 获取指定订单的套餐价格代码（不包含基础套餐）
        /// </summary>
        /// <param name="order">BookOrder</param>
        /// <returns></returns>
        public RateCode GetRateCodeData(BookOrder order)
        {
            if (string.IsNullOrWhiteSpace(order.RateCode))
            {
                return null;
            }
            var list = GetRateCodesByOrder(order);
            return list.FirstOrDefault(r => r.Code == order.RateCode);
        }



        private List<RateCodeCacheItem> GetRateCodesInDB(int RentalLength, string PickUpRegionCode, string AWD)
        {
            // 获取区域信息，并查询对应的国家信息
            var region = _regionManager.GetRegion(PickUpRegionCode);
            if (region == null)
            {
                throw new UserFriendlyException(string.Format("无效的地区编号（{0}）", PickUpRegionCode));
            }

            var countryCode = region.CountryCode;
            var countryName = region.CountryName;

            // 1.获取指定地区编号或者所属国家默认的套餐价格代码
            //      第一组筛选条件RegionCode等于换车城市的PickUpRegionCode 或者 所在国家编号.名称相同并且地区编号为空（RegionCode）
            var query = from c in _RateCodeRepository.GetAll()
                        where c.RegionCode == PickUpRegionCode ||
                           (c.CountryCode == countryCode && c.CountryName == countryName && c.RegionCode == "")
                        select c;

            //      第二组筛选条件为:开始时间小于等于租车时长，并且结束时间大于租车时长（如果RenEnd等于0的话 租车时长需要小于等于365）
            query = query.Where(c => c.RenStart <= RentalLength)
                .Where(c => c.RenEnd >= RentalLength || (c.RenEnd == 0 && 365 >= RentalLength));

            //      第三组筛选条件：如果 AWD 不为空，则取AWDList 包含 ^AWD^ ，其中（^）为分隔符，
            //                      否则就只取 AwdDepandant=0 或者 AWDList 为空的
            var realAWD = _AWDManager.GetRealAWDCode(AWD);
            if (!string.IsNullOrEmpty(realAWD))
            {
                //  条件，AWDList包含patternAWD 或者AwdDepandant等于false,或者AWDList不为空
                var patternAWD = string.Format("^{0}^", realAWD);
                query = query.Where(c => c.AWDList.Contains(patternAWD)
                                        || c.AwdDepandant == false
                                        || (c.AWDList == null || c.AWDList.Trim() == string.Empty));
            }
            else
            {
                //  条件：只取 AwdDepandant=0 或者 AWDList 为空的
                query = query.Where(c => c.AwdDepandant == false || (c.AWDList == null || c.AWDList.Trim() == string.Empty));
            }

            // 2.只取最新3条套餐价格代码（按 是否绑定AWD 和 修改时间）
            var list = query
               .OrderByDescending(c => c.AwdDepandant)
               .ThenByDescending(c => c.ModifyDate)
               .Take(4)
               .ToList();

            // 3.如果没有默认套餐，则插入 Code=空 的默认套餐
            if (!list.Exists(r => r.IsDefault == true))
            {
                list.Insert(0, new RateCode
                {
                    Code = OutBoundConsts.DEFAULT_RATE_CODE,
                    Name = OutBoundConsts.DEFAULT_RATE_NAME
                });
            }

            var data = _objectMapper.Map<List<RateCodeCacheItem>>(list);
            return data;
        }

       
    }
}
